package com.linkoog.devtools.code_generator.database.dao;

import com.linkoog.devtools.code_generator.database.domain.ConnectionInfo;
import com.linkoog.devtools.code_generator.database.domain.DbType;
import com.linkoog.devtools.code_generator.util.PlaceholderUtils;
import org.jetbrains.annotations.NotNull;
import org.apache.commons.lang3.StringUtils;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.HashMap;
import java.util.Map;

public abstract class AbstractDatabaseDao implements DatabaseDao{


    protected final ConnectionInfo connectionInfo;

    protected Connection connection;


    public AbstractDatabaseDao(@NotNull ConnectionInfo connectionInfo){
        this.connectionInfo = connectionInfo;
        if (this.connectionInfo.getDatabase() == null){
            this.connectionInfo.setDatabase("");
        }

    }

    public ConnectionInfo getConnectionInfo() {
        return connectionInfo;
    }

    @Override
    public Connection getConnection() {
        try {
            if (connection== null || connection.isClosed()) {
                synchronized (AbstractDatabaseDao.class) {
                    if (connection == null || connection.isClosed()) {
                        connection = newConnection();
                    }
                }
            }
        }catch (Exception e){
            throw new IllegalStateException("获取连接失败:" + e.getMessage());
        }
        return connection;
    }

    @Override
    public Connection getConnection(String database) {
        return newConnection(database);
    }

    public Connection newConnection() {
        return newConnection(null);
    }

    public Connection newConnection(String database) {
        DbType dbType = connectionInfo.getDbType();
        try {
            Class.forName(dbType.getDriver());
        } catch (ClassNotFoundException e) {
            throw new RuntimeException(e.getMessage(), e);
        }

        Map<String, String> map = new HashMap<>();
        map.put("host", connectionInfo.getHost());
        map.put("port", connectionInfo.getPort().toString());

        if (StringUtils.isNotBlank(database)){
            map.put("database", database);
        } else if (StringUtils.isNotBlank(connectionInfo.getDatabase())){
            map.put("database", connectionInfo.getDatabase());
        } else {
            map.put("database", dbType.getDefaultDatabase());
        }

        map.put("schema", connectionInfo.getSchema());

        String connectUrl = PlaceholderUtils.resolvePlaceholders(dbType.getConnectUrl(), map);

        try {
            //System.out.println(connectUrl);
            return DriverManager.getConnection(connectUrl, connectionInfo.getUsername(), connectionInfo.getPasswd());
        } catch (SQLException e) {
            throw new RuntimeException(e.getMessage(), e);
        }
    }

    @Override
    public void closeConnection(Connection conn) {
        if (conn != null) {
            try {
                conn.close();
            } catch (SQLException e) {
            }
        }
    }



}
